package com.lanhai.zhonglai.impl;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.lanhai.zhonglai.MsgCore;
import com.lanhai.zhonglai.beans.AgvDataBean;
import com.lanhai.zhonglai.enums.AgvMountTypeEnum;
import com.lanhai.zhonglai.enums.TransDirectionEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.lanhai.zhonglai.beans.AgvBean;
import com.lanhai.zhonglai.beans.DotBean;
import com.lanhai.zhonglai.dao.PowerDao;
import com.lanhai.zhonglai.dao.RoadDao;
import com.lanhai.zhonglai.dao.StationGroupDao;
import com.lanhai.zhonglai.interfaces.IAgv;
import com.lanhai.zhonglai.interfaces.IAgvEvent;
import com.lanhai.zhonglai.interfaces.IDot;
import com.lanhai.zhonglai.interfaces.IPower;
import com.lanhai.zhonglai.interfaces.IRoad;
import com.lanhai.zhonglai.interfaces.IStation;
import com.lanhai.zhonglai.mapper.PowerMapper;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Service
public class PowerImpl implements IPower {
    @Autowired
    PowerMapper powerMapper;

    @Autowired
    IDot iDot;

    @Autowired
    IAgv iAgv;

    @Autowired
    IAgvEvent iAgvEvent;


    @Autowired
    IRoad iRoad;

    @Autowired
    JedisPool jedisPool;

    @Autowired
    IStation iStation;

    static List<PowerDao> list = Collections.synchronizedList(new ArrayList<PowerDao>());
    Gson gson = new Gson();


    @Override
    public void init() {
        List<PowerDao> tmp = powerMapper.getPowerList();
        list.clear();

        if (tmp != null && tmp.size() > 0) {
            list.addAll(tmp);

            String key = "powerlocklist";
            Jedis jd = jedisPool.getResource();
            Map<String, String> rmap = jd.hgetAll(key);
            jd.close();

            if (rmap.size() > 0) {
                // 获取缓存数据

                for (PowerDao pp : list) {
                    String json = rmap.get(pp.getDotno() + "");
                    if (json != null) {
                        try {
                            PowerDao x = gson.fromJson(json, PowerDao.class);
                            pp.setIslock(x.isIslock());
                            pp.setAgvid(x.getAgvid());
                            pp.setLocktime(x.getLocktime());
                        } catch (Exception e) {
                        }
                    }
                }
            }
        }
    }


    /**
     * 小车回到工作岗位
     * 原处理方式带有线程  取消线程以免造成多辆小车同时离开充电桩
     */
    @Override
    public void agvBackToWork() {
//		 new Thread() {
//
//			@Override
//			public void run() {
        long t = System.currentTimeMillis();
        PowerDao power = null;
        for (PowerDao p : list) {
            //如果有续时间的直接返回
            if (p.getLocktime() > 0 && p.isIsdisable() == false && p.isIslock() && p.getAgvid() > 0 && p.getIsIsaddTime()) {
                power = p;
                break;
            } else if (p.getLocktime() > 0 && p.isIsdisable() == false && p.isIslock() && p.getAgvid() > 0 && p.getLocktime() <= t) {
                //预计解锁时间小于当前时间
                power = p;
                break;
            }
        }
        if (power == null) {
            return;
        }


        try (Jedis resource = jedisPool.getResource()) {
            //找路线  正背膜充电桩处理逻辑  带料的去正膜上料口
            if (power.getDotno() > 320 && power.getDotno() < 336) {


                String s = resource.get("agv_" + power.getAgvid());
                Gson gson = new Gson();
                AgvDataBean check = gson.fromJson(s, AgvDataBean.class);

                //查看agv装货状态 装料的去上料口
                if (check.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
                    //带料，只能去正膜上料
                    String process = "正膜上料";
                    StationGroupDao gbean = iStation.fetchNextInStation(power.getDotno(), power.getAgvid(), process, 0, true);
                    if (gbean != null) {
                        //释放
                        clearPower(power);
                        return;
                    } else {
                        //没有可用的，再休息5分钟
                        addTime(power);
                        return;
                    }
                } else {

                    //镀膜的充电桩
                    List<String> arr = Arrays.asList("正膜下料", "背膜下料", "ALD干法", "退火下料", "碱抛下料");
                    StationGroupDao sbean = iStation.fetchNextOutStation(440, 0, arr, false);
                    if (sbean == null) {
                        //没有可用的，再休息5分钟
                        addTime(power);
                        return;
                    }
					/*
					if(iStation.hasEmpty(Arrays.asList( "正膜下料" ,"背膜下料"))==false){
						//没有可用的，再休息5分钟
						power.setLocktime(System.currentTimeMillis()+5*60000);
						savePowerToRedis(power);
						return;
					}
					*/

                }
            }

        }


        if (power.getDotno() == 304 || power.getDotno() == 308) {
            //制绒处的充电桩
            if (iStation.hasEmpty(Arrays.asList("碱抛下料", "制绒下料")) == false) {
                //没有可用的，再休息5分钟
                addTime(power);
                return;
            }
        }

        //释放
        clearPower(power);
//			}

//		 }.start();
    }


    //续杯
    public void addTime(PowerDao power) {
        long l = System.currentTimeMillis();
        if (l >= power.getLocktime()) {
            power.setIsaddTime(true);
            power.setLocktime(+5 * 60000);
            savePowerToRedis(power);
        }
    }


    public void clearPower(PowerDao power) {
        AgvBean agv = null;
        if (power.getAgvid() > 0) {
            agv = iAgv.getBean(power.getAgvid());
        }
        if (agv == null) {
            power.setAgvid(0);
            power.setIslock(false);
            power.setLocktime(0);
            power.setIsaddTime(false);
            savePowerToRedis(power);
            return;
        }
        DotBean dotb = iDot.getBean(power.getDotno());
        if (dotb == null) {
            power.setAgvid(0);
            power.setIslock(false);
            power.setLocktime(0);
            power.setIsaddTime(false);
            savePowerToRedis(power);
            return;
        }

        //释放
        power.setAgvid(0);
        power.setIslock(false);
        power.setLocktime(0);
        power.setIsaddTime(false);
        savePowerToRedis(power);

        //回去的路
        agv.setNextRoad(dotb.getRouteRoad());
        agv.setFinishTrans(true);
        iAgv.saveCache(agv);
        iAgvEvent.finishTrans(agv);
    }


    @Override
    public void agvArrivedPower(int agvid, int dotno) {
        //再锁一次充电桩
        for (PowerDao p : list) {
            if (p.getDotno() == dotno) {
                if (p.getAgvid() != agvid || p.isIslock() == false) {
                    long t = System.currentTimeMillis() + 5 * 60000;  // 一次充5分钟
                    p.setIslock(true);
                    p.setLocktime(t);
                    p.setAgvid(agvid);
                    savePowerToRedis(p);
                    break;
                }
            }
        }
    }

    /**
     *
     */
    @Override
    public boolean agvToPower(int currentDot, AgvBean agv) {
        PowerDao power = null;
        for (PowerDao p : list) {
            if (p.getDecide() == currentDot && p.isIsdisable() == false && (p.isIslock() == false || p.getAgvid() == agv.getAgvId())) {
                power = p;
                break;
            }
        }

        if (power == null) {
            return false;
        }


        RoadDao roadDao = iRoad.getTransRoad(currentDot, power.getDotno()); //拿路线
        if (roadDao == null || roadDao.getId() <= 0) {
            return false;
        }
        //agv.setNextProcess(""); //保持原有的工序
        agv.setNextRoad(roadDao.getId());
        agv.setNexttStationName("去充电");
        iAgv.saveCache(agv);


        long t = System.currentTimeMillis() + 20 * 60000; //充20分钟
        power.setLocktime(t);
        power.setAgvid(agv.getAgvId());
        power.setIslock(true);
        savePowerToRedis(power);

        iAgvEvent.toRoad(agv, roadDao.getId());
        return true;
    }


    @Override
    public void unlockPowerByDot(int dotno) {
        PowerDao power = null;
        for (PowerDao p : list) {
            if (p.getDotno() == dotno) {
                power = p;
                break;
            }
        }
        if (power == null) {
            return;
        }

        if (power.getAgvid() > 0) {
            //解锁
            int cagv = power.getAgvid();
            power.setLocktime(0);
            power.setAgvid(0);
            power.setIslock(false);
            savePowerToRedis(power);

            // 小车返回
            AgvBean agv = iAgv.getBean(cagv);
            if (agv == null) {
                //解锁
                return;
            }
            DotBean dotb = iDot.getBean(dotno);
            if (dotb == null) {
                return;
            }
            //回去的路
            agv.setNextRoad(dotb.getRouteRoad());
            agv.setFinishTrans(true);
            agv.setNexttStationName("返回工作岗位");

            iAgv.saveCache(agv);
            iAgvEvent.finishTrans(agv);
        } else {
            //解锁
            power.setLocktime(0);
            power.setAgvid(0);
            power.setIslock(false);
            savePowerToRedis(power);
        }


    }


    void savePowerToRedis(PowerDao p) {
        new Thread() {

            @Override
            public void run() {
                String json = gson.toJson(p);
                String key = "powerlocklist";
                Jedis jd = jedisPool.getResource();
                jd.hset(key, "" + p.getDotno(), json);
                jd.close();
            }

        }.start();
    }


    @Override
    public boolean isLocked(int dotno) {
        boolean flag = false;
        for (PowerDao p : list) {
            if (p.getDotno() == dotno) {
                flag = p.isIslock();
                break;
            }
        }
        return flag;
    }


    @Override
    public void updatePowerState(int dotno, boolean disable) {
        for (PowerDao p : list) {
            if (p.getDotno() == dotno) {
                if (p.isIsdisable() != disable) {
                    p.setIsdisable(disable);
                    powerMapper.updateDisable(dotno, disable ? 1 : 0);
                }
                break;
            }
        }
    }


    @Override
    public void unlockPowerNotice(int dotno) {
        PowerDao power = null;
        for (PowerDao p : list) {
            if (p.getDotno() == dotno) {
                power = p;
                break;
            }
        }
        if (power == null || power.isIslock() == false) {
            return;
        }

        // 解锁
        power.setLocktime(0);
        power.setAgvid(0);
        power.setIslock(false);
        savePowerToRedis(power);

    }


    @Override
    public synchronized void unlockPowerByAgv(int agvid) {

        for (PowerDao power : list) {
            if (power.getAgvid() == agvid) {
                power.setLocktime(0);
                power.setAgvid(0);
                power.setIslock(false);
                savePowerToRedis(power);
            }
        }

    }


    @Override
    public boolean hasEmpty(int dotno) {
        boolean flag = false;
        //查找区域内+没有被禁用的+没有被锁定的充电桩
        for (PowerDao p : list) {
            if (p.getDecide() == dotno && p.isIsdisable() == false && p.isIslock() == false) {
                flag = true;
                break;
            }
        }
        return flag;
    }


}
